#ifndef __SCENE_H_
#define __SCENE_H_

#include <iostream>
#include <string>
#include "Global.h"
#include "Object.h"
#include <vector>
#include <fstream>
#include <unistd.h>
#include <sstream>
using namespace std;

using CStrRef = const std::string &;

/* ======================场景类====================== */
class Scene
{
public:
    /* 带参构造 */
    Scene(Player &p); // 锁定玩家，不用在去筛选是哪个玩家
    /* 带参构造 */
    Scene(Player &p,std::vector<Monster>& monsters); // 锁定玩家，不用在去筛选是哪个玩家
    /* 空白棋盘 */
    void Clear();
    /* 设定怪兽 */
    void InitMonsters();
    /* 打印场景 */
    void show();
    /* 判断是否满足战斗条件，满足则返回该怪兽地址 */
    Monster *IsPosEqual();
    /* 战斗规则函数 */
    void Fight(Monster *m);
    /* 玩家普攻怪兽 */
    void Player2Monster(Monster *m);
    /* 玩家暴击怪兽：随机事件 */
    void Player2Monster(Monster *m, int rate, int mutiple);
    /* 怪兽普攻玩家 */
    void Monster2Player(Monster *m);
    /* 玩家逃跑：随机事件 */
    bool Escape(int rate);
    /* 刷新怪兽 */
    void RefreshMonster(Monster *m);
    const std::vector<Monster> &GetMonsters();
    // void SetMonsters(const std::vector<Monster>monsters);
    const std::vector<TreasureBox> &GetTreasureBoxes();
    // void SetTreasureBoxes(const std::vector<TreasureBox>treasureBoxes);

    void InitTreasureBox();
    bool IsOverlappingWithMonster(int x, int y);

    TreasureBox *TIsPosEqual();

    void OpenBox(TreasureBox *t);
    /* 创建目录 */
    static bool CreateDirectory(const std::string &path)
    {
        return system(("mkdir -p " + path).c_str()) == 0; //-p 参数表示递归创建目录，即如果父目录不存在也会一并创建
    }

    void SaveGame()
    {
        string playerName = p.GetName();
        string DataPath = "./存档/" + playerName;
        string playerFilePath = DataPath + "/player_data.txt";
        string monsterFilePath = DataPath + "/monster_data.txt";
        string treasureBoxesFilePath = DataPath + "/treasureBoxes_data.txt";
        string bagFilePath = DataPath + "/bag_data.txt";

        // 创建玩家文件夹
        if (!CreateDirectory(DataPath))
        {
            std::cerr << "创建目录失败: " << DataPath << std::endl;
            return;
        }

        p.SavePlayerData(playerFilePath);

        // 保存怪物数据
        // std::ofstream f(monsterFilePath, std::ios::out);
        //     if (!f.is_open())
        //     {
        //         std::cerr << "Failed to open file for saving: " << monsterFilePath << std::endl;
        //         return;
        //     }
        //     f.close();

        std::ofstream file(monsterFilePath, std::ios::out | std::ios::trunc);
        if (!file.is_open())
        {
            std::cerr << "Failed to open file for saving: " << monsterFilePath << std::endl;
            return;
        }
        file << "Version 1\n"; // 添加版本控制
        for (auto &monster : monsters)
        {
            monster.SaveMonsterData(file);
            if (!file)
            {
                std::cerr << "Error writing monster data to file." << std::endl;
                file.close();
                return;
            }
        }
        file.close();a
        a
        

        if (file.fail())
        {
            std::cerr << "Error occurred while closing the file." << std::endl;
        }
        else
        {
            std::cout << "Monster data successfully saved to " << monsterFilePath << std::endl;
        }

        // for (auto &monster : monsters)
        // {
        //     monster.SaveMonsterData(monsterFilePath);
        // }

        // 保存宝箱数据
        // std::ofstream ff(treasureBoxesFilePath, std::ios::out);
        //     if (!ff.is_open())
        //     {
        //         std::cerr << "Failed to open file for saving: " << treasureBoxesFilePath << std::endl;
        //         return;
        //     }
        //     ff.close();
        for (auto &box : treasureBoxes)
        {
            box.SaveTreasureBoxData(treasureBoxesFilePath);
        }

        /* 保存背包 */
        for (auto &prop : p.GetBag()->GetProps())
        {
            p.GetBag()->Save(bagFilePath);
        }
        std::cout << "玩家信息已保存至 " << DataPath << std::endl;
    }

    /* 读档 */
    void LoadGame(const std::string &playerName, Player &p)
    {
        // 构建数据文件路径
        std::string DataPath = "./存档/" + playerName;
        std::string playerFilePath = DataPath + "/player_data.txt";
        std::string monsterFilePath = DataPath + "/monster_data.txt";
        std::string treasureBoxesFilePath = DataPath + "/treasureBoxes_data.txt";
        std::string bagFilePath = DataPath + "/bag_data.txt";

        // 加载玩家数据
        std::ifstream playerFile(playerFilePath);
        if (!playerFile.is_open())
        {
            std::cerr << "Failed to open player data file for loading: " << playerFilePath << std::endl;
            return;
        }
        std::string line;
        while (std::getline(playerFile, line))
        {
            if (line == "PlayerInfo")
            {
                std::string name;
                std::string symbol;
                int hp, attack, defends, exp, money, level, x, y;
                playerFile >> name >> hp >> money >> attack >> defends >> level >> exp >> symbol >> x >> y;
                p.SetX(x);
                p.SetY(y);
                p.SetSymbol(symbol);
                p.SetHP(hp);
                p.SetMoney(money);
                p.SetAttack(attack);
                p.SetDefends(defends);
                p.SetExp(exp);
                p.SetLevel(level);
                break; // 如果找到了玩家信息，可以退出循环
            }
        }
        playerFile.close();

        // 加载怪物数据
        // std::ifstream monsterFile(monsterFilePath);
        // if (!monsterFile.is_open())
        // {
        //     std::cerr << "Failed to open monster data file for loading: " << monsterFilePath << std::endl;
        //     return;
        // }

        // monsters.clear(); // 清空当前的怪物数据

        std::ifstream monsterFile(monsterFilePath);
        if (!monsterFile.is_open())
        {
            std::cerr << "Failed to open monster data file for loading: " << monsterFilePath << std::endl;
            return;
        }

        std::string version;
        std::getline(monsterFile, version); // 读取版本信息

        monsters.clear(); // 清空现有怪物列表

        while (std::getline(monsterFile, line))
        {
            if (line == "MonsterInfo")
            {
                std::string name, symbol;
                int hp, attack, defends, exp, money, x, y;
                if (monsterFile >> name >> hp >> money >> attack >> defends >> exp >> symbol >> x >> y)
                {
                    sleep(1);
                    monsters.push_back(Monster(x, y, name, symbol, hp, attack, defends, exp, money));
                    // 可选：跳过当前行的剩余部分（如果有的话）
                    std::getline(monsterFile, line);
                }
                else
                {
                    // 如果读取失败，输出错误信息并尝试继续读取下一行
                    std::cerr << "Failed to read monster data from file. Skipping line." << std::endl;
                    // 注意：这里我们没有调用 monsterFile.clear() 或 monsterFile.ignore()，
                    // 因为 std::getline 已经帮助我们跳过了可能出错的那一行。
                }
            }
        }
        monsterFile.close();

        // 加载宝箱数据
        std::ifstream treasureBoxFile(treasureBoxesFilePath);
        if (!treasureBoxFile.is_open())
        {
            std::cerr << "Failed to open treasure box data file for loading: " << treasureBoxesFilePath << std::endl;
            return;
        }

        treasureBoxes.clear(); // 清空当前的宝箱数据
        while (std::getline(treasureBoxFile, line))
        {
            if (line == "TreasureBoxInfo")
            { // 注意这里应该是 TreasureBoxInfo 而不是 TreasureBoxesInfo
                std::string name, symbol;
                int hp, attack, defends, exp, money, x, y;
                // 注意：这里假设宝箱没有 maxHP 属性，如果有则需要添加
                if (treasureBoxFile >> name >> x >> y >> attack >> defends >> hp >> money >> symbol)
                {
                    treasureBoxes.push_back(TreasureBox(x, y, name, symbol, money, hp, attack, defends));
                    // 可选：跳过当前行的剩余部分（如果有的话）
                    std::getline(treasureBoxFile, line);
                }
                else
                {
                    std::cerr << "Failed to read treasure box data from file. Skipping line." << std::endl;
                }
            }
        }
        treasureBoxFile.close();

        /* 加载背包 */

        std::ifstream bagFile(bagFilePath);
        if (!bagFile.is_open())
        {
            std::cerr << "无法打开文件进行读取: " << bagFilePath << std::endl;
            return;
        }

        // 清空当前背包内容
        p.GetBag()->ClearProps();

        std::string goodsName;
        int goodsMoney;

        //     while (bagFile >> goodsName >> goodsMoney) {
        //         // 根据 goodsName 和 goodsMoney 创建对应的 Prop 对象
        //         PropPtr prop = std::make_shared<Prop>(goodsMoney, goodsName);
        //         std::cout << "";
        //         // 添加到背包中
        //         props.push_back(prop);

        // }
        while (std::getline(bagFile, line))
        {
            std::istringstream iss(line);
            if (std::getline(iss, goodsName, ',') && iss >> goodsMoney)
            {
                PropPtr prop = std::make_shared<Prop>(goodsMoney, goodsName);
                p.GetBag()->Insert(prop);
                std::cout << goodsName << " 读取背包成功 " << std::endl;
                sleep(2);
            }
        }
        bagFile.close();

        std::cout << "已读取玩家存档: " << playerName << std::endl;
    }

private:
    std::string Map[MapSize][MapSize];
    std::vector<Monster> monsters;
    std::vector<TreasureBox> treasureBoxes;
    std::vector<PropPtr> props;
    Player &p;
};

#endif